package com.ytjj.qmyx.admin.service.impl;

import com.github.pagehelper.PageHelper;
import com.ytjj.qmyx.admin.constants.SysConfigConstants;
import com.ytjj.qmyx.admin.dao.MenuDao;
import com.ytjj.qmyx.admin.mapper.*;
import com.ytjj.qmyx.admin.model.*;
import com.ytjj.qmyx.admin.model.request.RoleRequest;
import com.ytjj.qmyx.admin.model.request.UpdateButtonRequest;
import com.ytjj.qmyx.admin.model.request.UpdateMenuRequest;
import com.ytjj.qmyx.admin.model.response.MenuTreeResponse;
import com.ytjj.qmyx.admin.service.RoleService;
import com.ytjj.qmyx.admin.utils.TreeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RoleServiceImpl implements RoleService {

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private MenuMapper menuMapper;

    @Resource
    private MenuDao menuDao;

    @Resource
    private RolePermissionRelationMapper rolePermissionRelationMapper;

    @Resource
    private RoleMenuRelationMapper roleMenuRelationMapper;

    @Resource
    private AdminRoleRelationMapper adminRoleRelationMapper;

    @Resource
    private AdminMapper adminMapper;

    @Override
    public List<Role> list() {
        RoleExample roleExample = new RoleExample();
        roleExample.createCriteria().andStatusEqualTo((byte) 1);
        return roleMapper.selectByExample(roleExample);
    }

    @Override
    public List<Role> list(RoleRequest roleRequest) {
        PageHelper.startPage(roleRequest.getPageNum(), roleRequest.getPageSize());
        roleRequest.setRoleType(SysConfigConstants.Role_Type.TYPE_1);
        List<Role> roles = roleMapper.selectRoleList(roleRequest);
        return roles;
    }

    @Override
    public List<Role> bankerListPage(RoleRequest roleRequest) {
        PageHelper.startPage(roleRequest.getPageNum(), roleRequest.getPageSize());
        roleRequest.setRoleType(SysConfigConstants.Role_Type.TYPE_2);
        return roleMapper.selectRoleList(roleRequest);
    }

    @Override
    public List<Role> adminList() {
        RoleExample roleExample = new RoleExample();
        roleExample.createCriteria().andRoleTypeEqualTo(SysConfigConstants.Role_Type.TYPE_1);
        return roleMapper.selectByExample(roleExample);
    }

    @Override
    public List<Role> bankerList() {
        RoleExample roleExample = new RoleExample();
        roleExample.createCriteria().andRoleTypeEqualTo(SysConfigConstants.Role_Type.TYPE_2);
        return roleMapper.selectByExample(roleExample);
    }

    @Override
    public int create(Role role) {
        role.setCreateTime(new Date());
        role.setRoleType(SysConfigConstants.Role_Type.TYPE_1);
        role.setStatus(SysConfigConstants.STATUS_1);
        return roleMapper.insert(role);
    }

    @Override
    public int bankerCreate(Role role) {
        role.setCreateTime(new Date());
        role.setRoleType(SysConfigConstants.Role_Type.TYPE_2);
        role.setStatus(SysConfigConstants.STATUS_1);
        return roleMapper.insert(role);
    }

    @Override
    public int update(Role role) {
        role.setUpdateTime(new Date());
        return roleMapper.updateByPrimaryKeySelective(role);
    }

    @Override
    public int delete(List<Integer> ids) {
        RoleExample example = new RoleExample();
        example.createCriteria().andIdIn(ids);
        int count = roleMapper.deleteByExample(example);
        // 删除缓存
        // adminCacheService.delResourceListByRoleIds(ids);
        return count;
    }

    @Override
    public List<Permission> getPermissionListById(Integer roleId) {
        return roleMapper.getPermissionListById(roleId);
    }

    @Override
    public int updatePermission(Integer roleId, List<Integer> permissionIds) {
        //先删除原有关系
        RolePermissionRelationExample example = new RolePermissionRelationExample();
        example.createCriteria().andRoleIdEqualTo(roleId);
        rolePermissionRelationMapper.deleteByExample(example);
        //批量插入新关系
        List<RolePermissionRelation> relationList = new ArrayList<>();
        for (Integer permissionId : permissionIds) {
            RolePermissionRelation relation = new RolePermissionRelation();
            relation.setRoleId(roleId);
            relation.setPermissionId(permissionId);
            relationList.add(relation);
        }
        return rolePermissionRelationMapper.insertList(relationList);
    }

    @Override
    public Map<String, Object> getMenuListById(Integer roleId) {
        MenuExample menuExample = new MenuExample();
        List<Menu> menus = menuMapper.selectByExample(menuExample);
        List<Integer> checkedIds = roleMapper.selectCheckedIds(roleId);
        List<MenuTreeResponse> menuTreeResponses = TreeUtil.getCloneData(menus);
        List<MenuTreeResponse> treeData = TreeUtil.getTreeList(menuTreeResponses);
        treeData = treeData.stream().sorted(Comparator.comparing(MenuTreeResponse::getSort)).collect(Collectors.toList());
        Map<String, Object> data = new HashMap<>();
        data.put("menu", treeData);
        data.put("checkedIds", checkedIds);
        return data;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateMenu(UpdateMenuRequest updateMenuRequest) {
        log.debug("===updateMenuRequest==={}", updateMenuRequest);
        // 先删除原有关系
        RoleMenuRelationExample example = new RoleMenuRelationExample();
        example.createCriteria().andRoleIdEqualTo(updateMenuRequest.getRoleId());
        roleMenuRelationMapper.deleteByExample(example);
        if (CollectionUtils.isEmpty(updateMenuRequest.getMenuIds())){
            return 0;
        }
        //查询传过来的id是菜单还是按钮
        List<Menu> MenusAndButton = menuMapper.selectTypeByid(updateMenuRequest.getMenuIds());

        for (Menu m : MenusAndButton) {
            RoleMenuRelation relation = new RoleMenuRelation();
            relation.setRoleId(updateMenuRequest.getRoleId());
            relation.setMenuId(m.getId());
            relation.setMenuType(m.getType());
            roleMenuRelationMapper.insert(relation);
            menuDao.updateStatusByMenId(m.getId());
        }
        return updateMenuRequest.getMenuIds().size();
    }

    @Override
    public List<Map<String, Object>> buttonList(Integer roleId) {
        List<Map<String, Object>> buttonTree = new ArrayList<>();

        MenuExample menuExample = new MenuExample();
        menuExample.createCriteria().andTypeEqualTo((byte) 1);
        List<Menu> menus = menuMapper.selectByExample(menuExample).stream()
                .filter(item -> StringUtils.isNotBlank(item.getMenuPreCode())).collect(Collectors.toList());

        List<Menu> children = new ArrayList<>();
        for (Menu menu : menus) {
            MenuExample criteria = new MenuExample();
            criteria.createCriteria().andTypeEqualTo((byte) 1).andMenuPreCodeEqualTo(String.valueOf(menu.getId()));
            List<Menu> counts = menuMapper.selectByExample(criteria);
            if (counts.size() == 0) {
                children.add(menu);
            }
        }
        for (Menu menu : children) {
            Map<String, Object> map = new HashMap<>();
            // 查询每个页面的所有选中的按钮
            List<Menu> checkButtonList = menuDao.selPageButton(String.valueOf(menu.getId()), roleId);

            // 查询每个页面的所有按钮
            MenuExample me = new MenuExample();
            me.createCriteria().andTypeEqualTo((byte) 2).andMenuPreCodeEqualTo(String.valueOf(menu.getId()));
            List<Menu> buttonList = menuMapper.selectByExample(me);

            map.put("title", menu.getTitle());
            map.put("buttonList", buttonList);
            map.put("checkButtonList", checkButtonList);
            buttonTree.add(map);
        }

        return buttonTree;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateButton(UpdateButtonRequest updateButtonRequest) {

        // 去掉角色对应的按钮权限为 0
        menuDao.updateButtonPerm(updateButtonRequest.getRoleId());
        // 先删除原有关系
        RoleMenuRelationExample example = new RoleMenuRelationExample();
        example.createCriteria().andRoleIdEqualTo(updateButtonRequest.getRoleId()).andMenuTypeEqualTo((byte) 2);
        roleMenuRelationMapper.deleteByExample(example);

        //批量插入新关系
        if (!CollectionUtils.isEmpty(updateButtonRequest.getButtonIds())) {
            for (Integer buttonId : updateButtonRequest.getButtonIds()) {
                RoleMenuRelation relation = new RoleMenuRelation();
                relation.setRoleId(updateButtonRequest.getRoleId());
                relation.setMenuId(buttonId);
                relation.setMenuType((byte) 2);
                roleMenuRelationMapper.insert(relation);
                menuDao.updateStatusByMenId(buttonId);
            }
        }
        return updateButtonRequest.getButtonIds().size();
    }

    @Override
    public int deleteIsExist(Integer id) {
        return roleMapper.deleteIsExist(id);
    }

    @Override
    public int RoleList(Integer id) {
        return roleMapper.RoleList(id);
    }

    @Override
    public int updateStatusById(Integer id, Integer status) {
        //查询该角色下的账号
        List<Integer> adminIds = adminRoleRelationMapper.selectById(id);
        //判断角色状态为0,角色下的账号全部关闭,角色状态为1,角色下的账号全部开启
        if (!CollectionUtils.isEmpty(adminIds)){
            switch (status){
                case 0:
                   adminMapper.updateStatusByIds(adminIds,0);
                   break;
                case 1:
                    adminMapper.updateStatusByIds(adminIds,1);
                    break;
            }
        }
        return roleMapper.updateStatusById(id, status);
    }

    @Override
    public List<Role> selectByRoleCode(String roleCode) {
        return roleMapper.selectByRoleCode(roleCode);
    }

    @Override
    public List<Role> selectByRoleName(String roleName) {
        return roleMapper.selectByRoleName(roleName);
    }

    @Override
    public Integer deleteAll() {
        List<Integer> ids=  roleMapper.findAdminId();
        Integer count = roleMapper.deleteAll(ids);
        return  count;
    }
}
